package tr.edu.ege.kipler.syntax.atomicformula;

import tr.edu.ege.kipler.syntax.Name;
import tr.edu.ege.kipler.syntax.NameManager;
import tr.edu.ege.kipler.syntax.WorldElementVisitor;
import tr.edu.ege.kipler.syntax.concept.Concept;

/**
 * This class represents a type of assertional axiom in description logics that
 * is asserting that an individual is an instance of a concept.
 * 
 * @author İnanç Seylan
 * 
 */
public class ConceptAssertion extends Formula {
	/**
	 * The concept that this individual is an instance of
	 */
	private Concept concept;

	/**
	 * The name of this individual
	 */
	private Name name;

	/**
	 * Default constructor
	 * 
	 */
	public ConceptAssertion() {

	}

	/**
	 * Constructor to initialize all the fields of this class by the given ones.
	 * 
	 * @param concept
	 *            The concept
	 * @param name
	 *            The individual's name
	 */
	public ConceptAssertion(Concept concept, String name) {
		setConcept(concept);
		setName(name);
	}

	/**
	 * @return the concept of this assertion. This concept can be composite,
	 *         i.e. made up of simpler concepts.
	 */
	public Concept getConcept() {
		return concept;
	}

	/**
	 * Sets the concept of this assertion.
	 * 
	 * @param concept
	 *            The concept
	 */
	public void setConcept(Concept concept) {
		this.concept = concept;
	}

	/**
	 * @return the name of the individual
	 */
	public String getName() {
		return name.toString();
	}

	/**
	 * Sets the name of the individual
	 * 
	 * @param name
	 *            the name of the individual
	 */
	public void setName(String name) {
		this.name = NameManager.getInstance().getName(name);
	}

	/**
	 * @see tr.edu.ege.seagent.alcbi.syntax.Formula#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj != null && (obj.getClass().equals(this.getClass()))) {
			ConceptAssertion other = (ConceptAssertion) obj;
			return (this.getConcept().equals(other.getConcept()) && this.name
					.equals(other.name));
		}
		return false;
	}

	/**
	 * @see tr.edu.ege.seagent.alcbi.syntax.Formula#hashCode()
	 */
	@Override
	public int hashCode() {
		return 17 * 37 + getConcept().hashCode() + getName().hashCode();
	}

	public ConceptAssertion copy() {
		ConceptAssertion ca = new ConceptAssertion();
		ca.name = name.copy();
		ca.setConcept(getConcept().copy());
		return ca;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append(getConcept());
		buffer.append("(");
		buffer.append(NameManager.getInstance().toQname(getName()));
		buffer.append(")");
		return buffer.toString();
	}

	public boolean isNegated() {
		return getConcept().isNegated();
	}

	public ConceptAssertion toggleNegated() {
		setConcept(getConcept().toggleNegated());
		return this;
	}

	public void accept(WorldElementVisitor v) {
		v.visitConceptAssertion(this);
	}

}
